Amazon CloudWatch SyntheticsでCanary実行がタイムアウトした時にもアラームを発生させたい(AWS CDK)
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、Amazon CloudWatch SyntheticsでのCanary実行がタイムアウトした時にもアラームを発生させる実装をAWS CDKで実装してみました。
前回の実装ではCanary実行のタイムアウトに対応できなかった
以前に下記エントリでCloudWatch SyntheticsによるURL監視で失敗を検知したらCloudWatch Alarmでアラームを発生させる(およびSNSトピックによる通知をする)実装をCDKで行いました。
この実装のうちCloudWatch Alarmのリソースの実装を抜粋したものが下記です。
const canaryAlarm = new cloudwatch.Alarm(this, 'canary-alarm', { alarmName: 'canary-alarm', metric: canary.metricFailed(), evaluationPeriods: 1, threshold: 1, statistic: cloudwatch.Statistic.SUM, comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, period: cdk.Duration.minutes(10), });
しかし上記の実装だと、Canary実行がタイムアウトした場合に、CloudWatch Alarmではデータ不足
となってアラームが発生しません。
Canary実行のタイムアウトは、ブラウザでプロンプト表示が行われるなど監視スクリプト(pupetter)での処理が進められなくなった場合に発生します。例えば下記のプロンプト表示が行われるサイトを監視対象とした場合だと、
下記のようにCanary実行がNo test result returned.Connection timed out after XXXXXXms
というタイムアウトの失敗となります。
するとCloudWatch Alarm側ではデータ不足
となりアラームは発生しません。
そこで今回はそのようなサイトの監視にも対応できるように、Canaryの実行結果が通常の失敗およびタイムアウトのいずれでもCloudWatch Alarmでアラーム発生させる実装をしてみます。
Canary実行のタイムアウト時にもアラームを発生させる
CDKコード
import * as path from 'path'; import * as cdk from '@aws-cdk/core'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as synthetics from '@aws-cdk/aws-synthetics'; export class AwsCdkAppStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) { super(scope, id, props); const canary = new synthetics.Canary(this, 'WebsiteCanary', { canaryName: `website-canary`, schedule: synthetics.Schedule.rate(cdk.Duration.minutes(3)), runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_2, test: synthetics.Test.custom({ code: synthetics.Code.fromAsset( path.join(__dirname, `../src/lambda/website-canary-handler`) ), handler: 'index.handler', }), environmentVariables: { URL: process.env.MONITORED_URL!, }, }); new cloudwatch.Alarm(this, 'canary-alarm', { alarmName: 'canary-alarm', metric: canary.metricSuccessPercent(), evaluationPeriods: 1, threshold: 100, statistic: cloudwatch.Statistic.SUM, comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD, period: cdk.Duration.minutes(3), treatMissingData: cloudwatch.TreatMissingData.BREACHING, }); } }
- CanaryとCloudWatch Alarmのリソースを作成しています。
treatMissingData
をBREACHING
とすることにより、Canary実行タイムアウトによるデータ欠落を不正(しきい値を超えている)として処理してアラームが発生するようにします。- 下記の設定により
3 分内の1データポイントのSuccessPercent < 100
というしきい値となります。評価期間内でCanary実行が一度でも失敗し成功率が100%を下回ればアラームが発生します。- メトリクス(metric):
metricSuccessPercent
- スレッショルド(threshold):
100
- 統計(statistic):
SUM
- 比較(comparisonOperator):
LESS_THAN_THRESHOLD
- メトリクス(metric):
これによりCanary実行が通常の失敗およびタイムアウトのいずれでもアラームが発生するようになります。
動作確認
Canary実行の成功時、失敗時、タイムアウト時の3通りの動作を確認してみます。(キャプチャの時系列が前後しているのは気にしないで下さい)
Canary成功時
Canaryの実行を成功させた際の動作です。
$ export MONITORED_URL=https://dev.classmethod.jp/ $ cdk deploy
アラームは発生していません。OK
状態となっています。
Canary失敗(通常)時
Canaryの実行を失敗(通常)させた際の動作です。
実行が失敗するURLを指定してCDKデプロイします。
$ export MONITORED_URL=https://dev.classmethod.jp/hoge $ cdk deploy
Canary実行が失敗しました。
アラームが発生しました。(Canary失敗からほぼノータイムでした。)
メトリクスの詳細を見るとSuccessPercentが0
となっています。
Canary失敗(タイムアウト)時
Canaryの実行をタイムアウトさせた際の動作です。
正常なURLを指定して一旦アラームをOK
状態に戻します。
実行がタイムアウトするURLを指定してCDKデプロイします。
$ export MONITORED_URL=https://1741r.csb.app/ $ cdk deploy
Canary実行がタイムアウトしました。
アラームが発生しました。(Canaryのタイムアウトから10分を要しました。データポイントが無い場合はある場合に比べて時間を要するようです)
メトリクスの詳細を見るとSuccessPercentは100
のままです。しかしデータ欠落時の設定によりしきい値を超えていると判断されているため、アラーム状態となります。
Canary実行を成功させるとOK
のデータポイントが記録されてCloudWatch AlarmはOK
状態となりました。
おわりに
Amazon CloudWatch SyntheticsでのCanary実行がタイムアウトした時にもアラームを発生させる実装をAWS CDKで実装してみました。
CloudWatch Alarmやメトリクスの理解が浅かったこと、そして実際にCanaryを実行してデバッグをするのに逐一待ち時間が掛かることなどにより検証がなかなか大変でした。
参考
以上